const { DataSystemMenuModel } = require("../models/sys_menu");
const { fail, CODE, success, routerTree } = require("../utils/utils");
const { getUserDataFromRedis } = require("../utils/userRedis");
class SystemMenuController {
  /**
   * @description 添加菜单
   * @param {Number} parent_id
   * @param {String} menu_name
   * @param {Number} order_num
   * @param {String} path
   * @param {String} component
   * @param {String} query
   * @param {Number} is_frame
   * @param {Number} is_cache
   * @param {String} menu_type
   * @param {String} visible
   * @param {String} status
   * @param {String} perms
   * @param {String} icon
   * @param {String} remark
   * @param {String} op_user_id
   */
  static async sysMenuAdd (ctx, next) {
    const {
      parent_id = 0,
      menu_name,
      order_num = 0,
      path,
      component,
      query,
      is_frame = 0,
      is_cache,
      menu_type,
      visible = "1",
      status = 1,
      perms,
      icon,
      remark,
    } = ctx.request.body;
    try {
      const { user_id: op_user_id } = ctx.state.user;
      if (!menu_name) {
        return (ctx.body = fail([], `请输入菜单名称`, CODE.BUSINESS_ERROR));
      }
      const sysMenuInfo = await DataSystemMenuModel.findBySystemMenuName({
        menu_name,
      });
      if (sysMenuInfo) {
        return (ctx.body = fail([], `菜单已存在`, CODE.BUSINESS_ERROR));
      }
      await DataSystemMenuModel.create({
        parent_id,
        menu_name,
        order_num,
        path,
        component,
        query,
        is_frame,
        is_cache,
        menu_type,
        visible,
        status,
        perms,
        icon,
        remark,
        op_user_id,
      });
      return (ctx.body = success([], `新增菜单成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }
  /**
   * @description 更新菜单
   * @param {Number} parent_id
   * @param {String} menu_name
   * @param {Number} order_num
   * @param {String} path
   * @param {String} component
   * @param {String} query
   * @param {Number} is_frame
   * @param {Number} is_cache
   * @param {String} menu_type
   * @param {String} visible
   * @param {String} status
   * @param {String} perms
   * @param {String} icon
   * @param {String} remark
   * @param {String} op_user_id
   * @param {Number} menu_id
   */
  static async sysMenuUpd (ctx, next) {
    const {
      parent_id,
      menu_name,
      order_num,
      path,
      component,
      query,
      is_frame,
      is_cache,
      menu_type,
      visible,
      status,
      perms,
      icon,
      remark,
      menu_id,
    } = ctx.request.body;
    try {
      const { user_id: op_user_id } = ctx.state.user;
      if (!menu_id) {
        return (ctx.body = fail([], `请输入必填项`, CODE.BUSINESS_ERROR));
      }
      const sysMenuInfo = await DataSystemMenuModel.findBySystemMenuNameNeId({
        menu_name,
        menu_id,
      });
      if (sysMenuInfo) {
        return (ctx.body = fail([], `菜单已存在`, CODE.BUSINESS_ERROR));
      }
      await DataSystemMenuModel.update({
        parent_id,
        menu_name,
        order_num,
        path,
        component,
        query,
        is_frame,
        is_cache,
        menu_type,
        visible,
        status,
        perms,
        icon,
        remark,
        op_user_id,
        menu_id,
      });
      return (ctx.body = success([], `菜单更新成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }
  /**
   * @description 删除菜单
   * @param {Number} menu_id
   */
  static async sysMenuDel (ctx, next) {
    const { menu_id } = ctx.request.body;

    try {
      const { user_id: op_user_id } = ctx.state.user;
      if (!menu_id) {
        return (ctx.body = fail([], `menu_id 获取失败`, CODE.BUSINESS_ERROR));
      }
      await DataSystemMenuModel.delete({ op_user_id, menu_id });
      return (ctx.body = success([], `菜单删除成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }
  /**
   * @description 批量删除菜单
   * @param {Array} ids
   */
  static async sysMenuDelByIds (ctx, next) {
    const { ids } = ctx.request.body;
    try {
      const { user_id: op_user_id } = ctx.state.user;
      if (!ids || !Array.isArray(ids) || ids.length === 0) {
        return (ctx.body = fail([], `删除失败`, CODE.BUSINESS_ERROR));
      }
      const result = await DataSystemMenuModel.deleteByIds({ op_user_id, ids });
      return (ctx.body = success([], `菜单删除成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }

  /**
   * @description 菜单列表
   * @param {String} name
   * @param {String} status
   */
  static async sysMenuList (ctx, next) {
    try {
      const { menu_name, status } = ctx.request.query;
      const { user_id } = ctx.state.user;
      const user_data = await getUserDataFromRedis(user_id);
      let result = [];
      const { user_type } = user_data.user_info;
      if (user_type === "00") {
        result = await DataSystemMenuModel.list({ menu_name, status });
      } else {
        result = await DataSystemMenuModel.listByUserId({
          user_id,
          menu_name,
          status,
        });
      }
      return (ctx.body = success(result, `获取菜单数据成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }

  /**
   * @description 菜单列表
   * @param {String} name
   * @param {String} status
   */
  static async getRouters (ctx, next) {
    try {
      const { user_id } = ctx.state.user;
      const user_data = await getUserDataFromRedis(user_id);
      let result = [];
      const { user_type } = user_data.user_info;
      if (user_type === "00") {
        result = await DataSystemMenuModel.routeList();
      } else {
        result = await DataSystemMenuModel.routeListByUserId({ user_id });
      }
      let menu = routerTree(result);
      return (ctx.body = success(menu, `获取菜单数据成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }

  /**
   * @description 按钮权限列表
   * @param {String} name
   * @param {String} status
   */
  static async sysPermissions (ctx, next) {
    try {
      const { user_id } = ctx.state.user;
      const user_data = await getUserDataFromRedis(user_id);
      const premissions = user_data.permissions;
      return (ctx.body = success(
        { premissions },
        `获取权限数据成功`,
        CODE.SUCCESS
      ));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }

  /**
   * @description 通过菜单id获取数据
   * @param {Number} menu_id
   */
  static async sysMenuById (ctx, next) {
    const { menu_id } = ctx.request.query;
    try {
      if (!menu_id) {
        return (ctx.body = fail([], `menu_id 获取失败`, CODE.BUSINESS_ERROR));
      }
      const result = await DataSystemMenuModel.findBySystemMenuId({
        menu_id: Number(menu_id),
      });
      return (ctx.body = success(result, `获取菜单数据成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }
  /**
   * @description 通过角色id获取数据
   * @param {Number} role_id
   */
  static async roleMenuTreeselect (ctx, next) {
    const { role_id } = ctx.request.body;
    try {
      if (!role_id) {
        return (ctx.body = fail([], `role_id 获取失败`, CODE.BUSINESS_ERROR));
      }
      const menuByRoleIds = await DataSystemMenuModel.findBySystemRoleId({
        role_id: Number(role_id),
      });
      const checkedKeys = menuByRoleIds.map(item => item.menu_id);
      const menusList = await DataSystemMenuModel.findAllMenu();
      const menus = (function makeTreeData (arr, parent_id) {
        let temp = []
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].parent_id === parent_id) {
            temp.push(arr[i])
            arr[i].children = makeTreeData(menusList, arr[i].id)
          }
        }
        return temp
      })(menusList, 0)
      return (ctx.body = success({ menus, checkedKeys }, `获取菜单数据成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }
  /**
   * @description 通过角色id获取数据
   * @param {Number} role_id
   */
  static async treeselect (ctx, next) {
    try {
      const menusList = await DataSystemMenuModel.findAllMenu();
      const menus = (function makeTreeData (arr, parent_id) {
        let temp = []
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].parent_id === parent_id) {
            temp.push(arr[i])
            arr[i].children = makeTreeData(menusList, arr[i].id)
          }
        }
        return temp
      })(menusList, 0)
      return (ctx.body = success({ menus }, `获取菜单数据成功`, CODE.SUCCESS));
    } catch (error) {
      return (ctx.body = fail([], error.message, CODE.BUSINESS_ERROR));
    }
  }

}

module.exports = {
  SystemMenuController,
};
